package com.distributer.product.service.impl;

import java.util.Map;
import java.util.concurrent.ArrayBlockingQueue;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import com.distributer.product.request.ProductRefreshRequest;
import com.distributer.product.request.ProductUpdateRequest;
import com.distributer.product.request.Request;
import com.distributer.product.service.AsyncRequestHandlerService;
import com.distributer.product.thread.RequestQueue;

@Service
public class AsyncRequestHandlerServiceImpl implements AsyncRequestHandlerService {

	private static final Logger LOGGER = LoggerFactory.getLogger(AsyncRequestHandlerServiceImpl.class);
	
	@Override
	public void requestHandler(Request request) {
		try {
			// 先做读请求去重处理
			RequestQueue requestQueue = RequestQueue.getInstance();
			Map<String, Boolean> flagMap = requestQueue.getFlagMap();
			// 如果是写请求直接进队列
			if (request instanceof ProductUpdateRequest) {
				flagMap.put(request.getJbProductCode(), true);
			}
			// 如果是读请求，进行读去重处理
			if (request instanceof ProductRefreshRequest) {
				// 第一次处理读请求
				Boolean flag = flagMap.get(request.getJbProductCode());
				if (flag == null) {
					flagMap.put(request.getJbProductCode(), false);
				}
				// 如果flag等于true,说明之前已经存在了写处理
				if (flag != null && flag) {
					flagMap.put(request.getJbProductCode(), false);
				}
				// 如果flag等于false，说明之前已经存在读请求，则直接忽略本次读请求进队列
				if (flag != null && !flag) {
					LOGGER.info("产品编码： "+ request.getJbProductCode()+" 已经存在缓存刷新请求！");
					return;
				}
			}
			// 根据产品编码的hash值进行取模选择一个处理队列
			ArrayBlockingQueue<Request> queue = gethashNumberByJbProductCode(request.getJbProductCode());
			queue.put(request);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private ArrayBlockingQueue<Request> gethashNumberByJbProductCode(String jbProductCode) {
		RequestQueue requestQueue = RequestQueue.getInstance();
		int h;
		int hash = (jbProductCode == null) ? 0 : (h = jbProductCode.hashCode()) ^ (h >>> 16);
		int index = hash & requestQueue.getRequestQueues().size() - 1;
		LOGGER.info("产品编码："+ jbProductCode+"，选择队列索引为： "+ index);
		return requestQueue.getQueueByIndex(index);
	}
}
